/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
 */
package td.domain;

import java.util.Date;

import td.domain.util.StatisticalComparison;

import com.googlecode.objectify.annotation.Embed;

/**
 * Any object that has statistics gathered on it.
 * 
 * @author Artem Shamsutdinov
 * 
 */
public abstract class Statistical extends ListCachedObject implements
		Comparable<Statistical> {

	private static final long serialVersionUID = -3696949661538418917L;

	protected String name = "";
	protected String description = "";

	// Statistics
	private Date createdDate;
	private Date lastThoughtReadDate;
	private Long numReferences = 0L;
	private Long numReferenced = 0L;
	private Long numTaggings = 0L;
	private Long numThoughtReads = 0L;
	private Long numTags = 0L;
	private Date lastTagged;

	@Embed
	public Restrictions restrictions;

	/**
	 * Keeps track of the current sort order for a given type of Statistics.
	 */
	public abstract StatisticalComparison getComparisonType();

	public Long getNumReads() {
		return numThoughtReads;
	}

	public void setNumReads(Long numReads) {
		this.numThoughtReads = numReads;
	}

	public Long getNumTaggings() {
		return numTaggings;
	}

	public void setNumTaggings(Long numTaggings) {
		this.numTaggings = numTaggings;
	}

	public Long getNumReferences() {
		return numReferences;
	}

	public void setNumReferences(Long numReferences) {
		this.numReferences = numReferences;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public Long getNumThoughtTaggings() {
		return numTaggings;
	}

	public Date getCreatedDate() {
		return createdDate;
	}

	public void setCreatedDate(Date createdDate) {
		this.createdDate = createdDate;
	}

	public Date getLastThoughtReadDate() {
		return lastThoughtReadDate;
	}

	public void setLastThoughtReadDate(Date lastReadDate) {
		this.lastThoughtReadDate = lastReadDate;
	}

	public Long getNumTags() {
		return numTags;
	}

	public void setNumTags(Long numTags) {
		this.numTags = numTags;
	}

	public Date getLastTagged() {
		return lastTagged;
	}

	public void setLastTagged(Date lastTagged) {
		this.lastTagged = lastTagged;
	}

	public Long getNumReferenced() {
		return numReferenced;
	}

	public void setNumReferenced(Long numReferenced) {
		this.numReferenced = numReferenced;
	}

	public Long getNumThoughtReads() {
		return numThoughtReads;
	}

	public void setNumThoughtReads(Long numThoughtReads) {
		this.numThoughtReads = numThoughtReads;
	}

	public Restrictions getRestrictions() {
		return restrictions;
	}

	public void setRestrictions(Restrictions restrictions) {
		this.restrictions = restrictions;
	}

	@Override
	public int compareTo(Statistical otherStats) {
		switch (getComparisonType()) {
		case ALPHABETIC:
			return this.name.compareTo(otherStats.name);
		case ALPHABETIC_REVERSE:
			return otherStats.name.compareTo(this.name);
		case CREATED_DATE:
			return otherStats.createdDate.compareTo(createdDate);
		case LAST_THOUGHT_READ_DATE:
			return otherStats.lastThoughtReadDate
					.compareTo(lastThoughtReadDate);
		case NUMBER_OF_THOUGHT_READS:
			return otherStats.numThoughtReads.compareTo(numThoughtReads);
		case NUMBER_OF_REFERENCES:
			return otherStats.numReferences.compareTo(numReferences);
		case NUMBER_OF_REFERENCED:
			return otherStats.numReferenced.compareTo(numReferenced);
		case NUMBER_OF_TAGGINGS:
			return otherStats.numTaggings.compareTo(numTaggings);
		case NUMBER_OF_TAGS:
			return otherStats.numTags.compareTo(numTags);
		case LAST_TAGGED_DATE:
			return otherStats.lastTagged.compareTo(lastTagged);
		default:
			throw new RuntimeException(
					"Unsupported comparison type or type that should have been handled at a more specific level.");
		}
	}
}
